-- 获取上个月或年份
local function getLastMonthOrYear(month, year)
    if month == 1 then
        month = 12
        year = year - 1
    else
        month = month - 1
    end
    return month, year
end

-- 获取当月最大天数
local function getMaxDaysInMonth(month, year)
    if month == 2 then
        -- 二月份，判断是否为闰年
        if (year % 4 == 0 and year % 100 ~= 0) or (year % 400 == 0) then
            return 29
        else
            return 28
        end
    elseif month == 4 or month == 6 or month == 9 or month == 11 then
        -- 四月、六月、九月、十一月，每月30天
        return 30
    else
        -- 其他月份，每月31天
        return 31
    end
end

local redisKeyPrefix = KEYS[1] -- redisKey前缀
local currentUserId = KEYS[2] -- 用户id
local year = tonumber(KEYS[3]) -- 年份
local month = tonumber(KEYS[4]) -- 月份
local redisKey = redisKeyPrefix .. ':' .. currentUserId .. ':' .. year .. ':' .. month;
local allCount = 0

while true do
    local signCountResult = redis.pcall("BITCOUNT", redisKey)
    -- 没有签到数据了, 跳过下面的计算直接返回结果
    if not signCountResult then
        break
    end

    -- 如果当月签到数等于当月最大天数,即满勤签到
    local maxDaysInMonth = getMaxDaysInMonth(month, year)
    if signCountResult == maxDaysInMonth then
        allCount = allCount + signCountResult
        month, year = getLastMonthOrYear(month, year)  -- 继续查询上个月的
    else
        -- 非满勤签到,则计算连续签到数
        local bitGetNumberTable = redis.pcall("BITFIELD", redisKey, "GET", "u" .. maxDaysInMonth, 0)

        -- 没有签到数据了, 跳过下面的计算直接返回结果
        if not bitGetNumberTable or not bitGetNumberTable[1] then
            break
        end

        local bitGetNumber = bitGetNumberTable[1]
        local count = 0
        while (bit.band(bitGetNumber, 1)) == 1 do
            --将数值和1 位与运算
            count = count + 1
            bitGetNumber = math.floor(bitGetNumber / 2)  -- 使用除法运算符并向下取整 即:bitGetNumber >>= 1
        end
        allCount = allCount + count
        break
    end
end

return allCount

